package com.community.process._1010.service.impl;

import cn.hutool.core.util.StrUtil;
import com.community.process._1010.common.api.ErrorAssert;
import com.community.process._1010.common.utils.mp.TreeNodeHelper;
import com.community.process._1010.common.utils.tree.TreeUtils;
import com.community.process._1010.dao.entity.ProcessCategory;
import com.community.process._1010.dao.entity.ProcessIngredients;
import com.community.process._1010.dao.mapper.ProcessCategoryMapper;
import com.community.process._1010.dao.mapper.ProcessIngredientsMapper;
import com.community.process._1010.dao.view.ProcessCategoryNodeView;
import com.community.process._1010.dao.view.ProcessCategoryView;
import com.community.process._1010.domains.ProcessCategoryDTO;
import com.community.process._1010.service.ProcessCategoryService;
import com.oneadds.lowcode.BaseServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author: Administrator to Zbs
 * @Date: 2024/9/6 星期五 13:09
 */
@Service
@RequiredArgsConstructor
public class ProcessCategoryServiceImpl extends BaseServiceImpl<ProcessCategoryMapper, ProcessCategory> implements ProcessCategoryService {

    @Override
    public ProcessCategoryView getProcessCategoryViewById(Long id) {
        return new ProcessCategoryView(this.getById(id));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addProcessCategory(ProcessCategoryDTO.CategoryAdd dto) {
        // 校验唯一标识
        this.isIdentifierAva(null, dto.getName());
        // 父级检查
        ProcessCategory parent = null;
        if (dto.getParentId() != null) {
            parent = this.getById(dto.getParentId());
            ErrorAssert.notNull(parent, "父级不存在!");
            dto.setType(parent.getType());
        }
        // 获取编码
        String treeCode = TreeNodeHelper.getNewCode(this.baseMapper, parent);
        Integer level = (parent == null) ? 1 : parent.getLevel() + 1;
        ProcessCategory category = new ProcessCategory(dto, level, treeCode);
        this.save(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editProcessCategory(ProcessCategoryDTO.CategoryUpdate dto) {
        // 校验唯一名称
        this.isIdentifierAva(dto.getId(), dto.getName());
        ProcessCategory category = this.getById(dto.getId());
        ErrorAssert.notNull(category, "分类不存在!");

        category.setName(dto.getName());
        category.setIcon(dto.getIcon());
        category.setSort(dto.getSort());

        // 更新
        this.updateById(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteProcessCategory(ProcessCategoryDTO.CategoryDelete dto) {
        ErrorAssert.isEmpty(dto.getIds(),"ID不能为空");

        dto.getIds().forEach(id -> {
            boolean exists = this.lambdaQuery()
                    .eq(ProcessCategory::getParentId, id)
                    .exists();
            ErrorAssert.isTrue(!exists,"选中分类含有子分类，不可删除，清先删除子分类");
        });
        this.lambdaUpdate().in(ProcessCategory::getId,dto.getIds()).remove();
    }

    @Override
    public List<ProcessCategoryNodeView> getPwItemCategoryNodeTree(ProcessCategoryDTO.CategoryPageSearch dto) {
        return TreeUtils.generateTrees(getPwItemCategoryList(dto));
    }

    @Override
    public List<ProcessCategoryNodeView> getPwItemCategoryList(ProcessCategoryDTO.CategoryPageSearch dto) {
        return this.getProcessCategoryList(dto).stream().map(ProcessCategoryNodeView::new).collect(Collectors.toList());
    }

    private List<ProcessCategory> getProcessCategoryList(ProcessCategoryDTO.CategoryPageSearch dto) {
        return this.lambdaQuery()
                .eq(dto.getParentId() != null,ProcessCategory::getParentId, dto.getParentId())
                .eq(dto.getType() != null,ProcessCategory::getType, dto.getType())
                .likeRight(StrUtil.isNotBlank(dto.getTreeCode()),ProcessCategory::getTreeCode, dto.getTreeCode())
                .orderByAsc(ProcessCategory::getSort)
                .orderByAsc(ProcessCategory::getTreeCode)
                .orderByDesc(ProcessCategory::getCreateTime)
                .list();
    }

    private void isIdentifierAva(Long id, String name) {
        boolean exists = this
                .lambdaQuery()
                .eq(ProcessCategory::getName, name)
                .ne(id != null,ProcessCategory::getId, id)
                .exists();
        ErrorAssert.isTrue(!exists, "分类名称重复");
    }
}
